package com.imooc.controller;

import com.imooc.pojo.Users;
import com.imooc.pojo.UsersVO;
import com.imooc.pojo.bo.ShopcartBO;
import com.imooc.pojo.bo.UserBO;
import com.imooc.service.UsersService;
import com.imooc.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 用户通行证
 */
@Api(value = "注册登录", tags = {"用于注册和登录的相关接口"})
@RestController
@RequestMapping("passport")
public class PassportController extends BaseController {

    @Autowired
    private UsersService usersService;
    @Autowired
    private RedisOperator redisOperator;

    @ApiOperation(value = "用户名是否存在", httpMethod = "GET")
    @GetMapping("usernameIsExist")
    public IMOOCJSONResult usernameIsExist(@RequestParam String username) {
        //1.判断用户名不可为空
        if (StringUtils.isBlank(username)) {
            return IMOOCJSONResult.errorMsg("用户名不能为空");
        }
        //2.查找注册的用户名是否存在
        boolean isExist = usersService.queryUsernameIsExist(username);
        if (isExist) {
            return IMOOCJSONResult.errorMsg("用户名已存在");
        }
        return IMOOCJSONResult.ok();
    }

    @ApiOperation(value = "用户注册", httpMethod = "POST")
    @PostMapping("regist")
    public IMOOCJSONResult regist(@RequestBody UserBO userBO,
                                  HttpServletRequest request,
                                  HttpServletResponse response) {
        String username = userBO.getUsername();
        String password = userBO.getPassword();
        String confirmPassword = userBO.getConfirmPassword();
        //1.判断用户名或密码不能为空
        if (StringUtils.isBlank(username) ||
                StringUtils.isBlank(password) ||
                StringUtils.isBlank(confirmPassword)) {
            return IMOOCJSONResult.errorMsg("用户名或密码不能为空");
        }
        //2.查询用户名是否存在
        boolean isExist = usersService.queryUsernameIsExist(username);
        if (isExist) {
            return IMOOCJSONResult.errorMsg("用户名已存在");
        }
        //3.判断密码长度不少于6
        if (password.length() < 6) {
            return IMOOCJSONResult.errorMsg("密码长度不能少于6");
        }
        //4.判断两次密码是否一致
        if (!StringUtils.equals(password, confirmPassword)) {
            return IMOOCJSONResult.errorMsg("两次密码不一致");
        }
        Users userResult = usersService.createUser(userBO);

        UsersVO usersVO = setTokenUser(userResult);

        //设置cookie
        CookieUtils.setCookie(request, response, "user",
                JsonUtils.objectToJson(usersVO), true);

        //同步购物车数据
        syncShopCartData(usersVO.getId(), request, response);

        return IMOOCJSONResult.ok();
    }

    @ApiOperation(value = "用户登录", httpMethod = "POST")
    @PostMapping("login")
    public IMOOCJSONResult login(@RequestBody UserBO userBO,
                                 HttpServletRequest request,
                                 HttpServletResponse response) {
        String username = userBO.getUsername();
        String password = userBO.getPassword();
        //1.判断用户名或密码不能为空
        if (StringUtils.isBlank(username) ||
                StringUtils.isBlank(password)) {
            return IMOOCJSONResult.errorMsg("用户名或密码不能为空");
        }
        String md5Password = MD5Utils.getMD5Str(userBO.getPassword());
        Users userResult = usersService.queryUserForLogin(userBO.getUsername(), md5Password);
        if (userResult == null) {
            return IMOOCJSONResult.errorMsg("用户名或密码错误");
        }
        UsersVO usersVO = setTokenUser(userResult);

        //设置cookie
        CookieUtils.setCookie(request, response, "user",
                JsonUtils.objectToJson(usersVO), true);
        //同步购物车数据
        syncShopCartData(userResult.getId(), request, response);
        return IMOOCJSONResult.ok(userResult);
    }

    /**
     * 注册成功以后，同步cookie和redis中的购物车数据
     */
    private void syncShopCartData(String userId,
                                  HttpServletRequest request,
                                  HttpServletResponse response) {
        /*
            1.redis中有数据：cookie中购物车有商品，如果与redis中的商品相同，直接删除redis中的商品，以cookie为准。（参考京东）
                           cookie中购物车为空，把redis数据同步至cookie
            2.redis中无数据：cookie中购物车有商品，直接把数据放入redis
                           cookie中购物车为空，不做任何处理
            最后要保持redis和cookie的购物车数据一致
         */
        //从redis里面拿购物车数据
        String shopCartRedis = redisOperator.get(FOODIE_SHOPCART + ":" + userId);
        //从cookie里面拿购物车数据
        String shopCartCookie = CookieUtils.getCookieValue(request, FOODIE_SHOPCART, true);
        if (StringUtils.isNotBlank(shopCartRedis)) {
            if (StringUtils.isNotBlank(shopCartCookie)) {
                //合并。有商品冲突，cookie覆盖redis
                List<ShopcartBO> shopCartListRedis = JsonUtils.jsonToList(shopCartRedis, ShopcartBO.class);
                List<ShopcartBO> shopCartListCookie = JsonUtils.jsonToList(shopCartCookie, ShopcartBO.class);
                List<String> specIdsCookie = shopCartListCookie.stream()
                        .map(ShopcartBO::getSpecId).collect(Collectors.toList());
                for (ShopcartBO scRedis : shopCartListRedis) {
                    if (!specIdsCookie.contains(scRedis.getSpecId())) {
                        shopCartListCookie.add(scRedis);
                    }
                }
                String newShopCartData = JsonUtils.objectToJson(shopCartListCookie);
                CookieUtils.setCookie(request, response, FOODIE_SHOPCART, newShopCartData, true);
                redisOperator.set(FOODIE_SHOPCART + ":" + userId, newShopCartData);
            } else {
                CookieUtils.setCookie(request, response, FOODIE_SHOPCART, shopCartRedis, true);
            }
        } else {
            if (StringUtils.isNotBlank(shopCartCookie)) {
                redisOperator.set(FOODIE_SHOPCART + ":" + userId, shopCartCookie);
            }
        }
    }

    @ApiOperation(value = "用户退出登录", httpMethod = "GET")
    @PostMapping("logout")
    public IMOOCJSONResult logout(@RequestParam String userId,
                                  HttpServletRequest request,
                                  HttpServletResponse response) {
        //设置cookie
        CookieUtils.deleteCookie(request, response, "user");
        // 用户退出登录，清除购物车
        CookieUtils.deleteCookie(request, response, FOODIE_SHOPCART);

        redisOperator.del(REDIS_USER_TOKEN + ":" + userId);

        return IMOOCJSONResult.ok();
    }

}
